<?php
namespace app\api\service;

use app\common\model\User;
use app\common\model\UserExtra;
use think\Db;
use think\Log;

class ActivityService
{
    private static $instance;

    public static function getInstance() {
        if (!(self::$instance instanceof self)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function participation($order_id) {
        $model_order = model('app\api\model\wanlshop\Order');
        $model_order_goods = model('app\api\model\wanlshop\OrderGoods');
        $goods_category = model('app\api\model\wanlshop\Goods');
        // 检查订单是否存在
        $order_info = $model_order->find($order_id);

        if ($order_info['shop_id'] != config('oem.OrderShopPrefix')) {
            return false;
        }
        // 获取目标分类下的商品ID列表（显式指定字段并校验格式）
        $category_id = (int)config('oem.CategoryIdPrefix');
        $goods_ids = $goods_category
            ->where('category_id', $category_id)
            ->column('id', 'id'); // 强制将id字段同时作为键名

// 类型校验并转换为一维数组
        if (!is_array($goods_ids)) {
            return true;
        }
        $goods_ids = array_values($goods_ids); // 保证为一维索引数组

// 分类下无商品时直接通过检查
        if (empty($goods_ids)) {
            return true;
        }
// 统计符合条件的商品总数量
        $totalNumber = $model_order_goods
            ->where('order_id', $order_info['id'])
            ->whereIn('goods_id', $goods_ids)
            ->sum('number');

        // 数量超过1时返回false
        if ($totalNumber > 1) {
            return false;
        }

        // 处理订单商品价格数值类型（明确字段别名）
        $order_goods_price = $model_order_goods
            ->where('order_id',$order_info['id'])
            ->sum('price');

        // 计算应得积分
        $get_score = $this->getOrderScore($order_goods_price);

        // 计算并更新星级
        $star_level = $this->getStarLevel($get_score);

        $user = User::get($order_info['user_id']);

        // 更新用户星级
        $user_extra = $this->currentUser($user,$star_level,$get_score);
        // 使用行级锁查询用户数据
        $get_user_extra = UserExtra::where('user_id', $user_extra['id'])
            ->find();
        if (!$get_user_extra) {
            return false;
        }
        $users = User::get($user_extra['id']);
        if($star_level > $users->star){
            $users->star = $star_level;
            $users->level = $star_level;
        }
        $users->save();
        // 更新用户积分
        $get_user_extra->score = bcadd($get_user_extra->score, $get_score, 2);
        $get_user_extra->star = $star_level;
        $get_user_extra->save();

        return true;
    }

    /**
     * @param $user
     * @param $star_level
     * @param $score
     * @return User|mixed
     * @throws \think\exception\DbException
     */
    private function currentUser($user,$star_level,$score)
    {
        $currentUser = $user;
        $firstIdPrefix = config('oem.FirstIdPrefix');
        $processedLevels = 0; // 实际处理的层级数
        for ($i = 0; $i < $star_level; $i++) {
//            $star_user = User::get($currentUser['pid'] ?? null);
            $star_user = User::get($currentUser->pid ?? null);

            // 终止条件1：父用户不存在
            if (!$star_user) break;

//            // 终止条件：父用户不存在 或 达到首ID前缀用户
//            if (!$star_user || $star_user->id == config('oem.FirstIdPrefix')) {
//                break;
//            }

            // 终止条件2：达到首ID前缀用户（处理前检查）
            if (str_starts_with((string)$star_user->id, $firstIdPrefix)) {
                break;
            }

            $star_user->score = bcadd($star_user->score, $score, 2);
            $star_user->save();

            $processedLevels++;
            // 指针上移准备下次查找
            $currentUser = $star_user;
        }
        // 星级与实际处理层数绑定（根据业务需求选择）
        $user->star = min($star_level, $processedLevels);
        $user->save();


        return $currentUser ;

    }
    /**
     * 计算订单得分
     * @param float $order_goods_price 订单商品价格
     * @return float 计算得到的得分
     */
    private function getOrderScore($order_goods_price)
    {
        $subOrderPrefix = config('oem.SubOrderPrefix');
        $munOrderPrefix = config('oem.MulOrderPrefix');

        if (!is_numeric($subOrderPrefix) || !is_numeric($munOrderPrefix)) {
            throw new \InvalidArgumentException('Invalid configuration values for SubOrderPrefix or MunOrderPrefix.');
        }

        // 验证输入是否为有效数值
        if (!is_numeric($order_goods_price)) {
            throw new \InvalidArgumentException('Invalid order_goods_price value.');
        }

        // 处理边界条件
        if ($order_goods_price <= $subOrderPrefix) {
            return 0;
        }

        // 计算分数
        $score = bcmul(bcsub((string)$order_goods_price, (string)$subOrderPrefix, 2), (string)$munOrderPrefix, 2);
        return $score;
    }


    public function getAncestors($maxLevel)
    {
        $ancestors = [];
        $current = $this;

        for ($i = 0; $i < $maxLevel; $i++) {
            $current = $current->pid ? User::get($current->pid) : null;
            if (!$current) break;
            $ancestors[] = $current;
        }

        return $ancestors;
    }
    /**
     * 根据用户积分获取对应的星级
     * @param int $score 用户当前积分
     * @return int 返回对应的星级
     */
    private function getStarLevel($score)
    {
        // 修正阈值数组顺序（严格从高到低）
        $thresholds = [
            13 => 55080, 12 => 46080, 11 => 23040, 10 => 11520, 9 => 5760,
            8  => 2880,  7  => 1440,  6  => 720,   5  => 360,
            4  => 180,   3  => 90,    2  => 45,    1  => 171
        ];

        // 按值降序排序保证匹配顺序
        arsort($thresholds);

        foreach ($thresholds as $star => $limit) {
            if ($score >= $limit) {
                return $star;
            }
        }

        return 0;
    }


}
